﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using NVelocity;
using NVelocity.App;
using NVelocity.Context;
using NVelocity.Runtime;
using Commons.Collections;
using System.Web;
using System.IO;

namespace Org.SpmisFramework.TemplateEngine
{
    /// <summary>
    /// 模板引擎
    /// </summary>
    public class VelocityHelper
    {
        private VelocityEngine velocity = null;
        private IContext context = null;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="templatDir">模板目录</param>
        public VelocityHelper(string templatDir)
        {
            InitVelocity(templatDir, Encoding.UTF8, Encoding.UTF8);
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="templatDir">模板目录</param>
        /// <param name="inputEncoding">输入模板文件编码</param>
        /// <param name="outputEncoding">输出内容编码</param>
        public VelocityHelper(string templatDir, Encoding inputEncoding, Encoding outputEncoding)
        {
            InitVelocity(templatDir, inputEncoding, outputEncoding);
        }

        /// <summary>
        /// 初始化模板引擎
        /// </summary>
        /// <param name="templatDir"></param>
        private void InitVelocity(string templatDir, Encoding inputEncoding, Encoding outputEncoding)
        {
            velocity = new VelocityEngine();

            //使用设置初始化VelocityEngine
            ExtendedProperties props = new ExtendedProperties();
            props.AddProperty(RuntimeConstants.RESOURCE_LOADER, "file");
            props.AddProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, templatDir);
            props.AddProperty(RuntimeConstants.INPUT_ENCODING, inputEncoding.HeaderName);
            props.AddProperty(RuntimeConstants.OUTPUT_ENCODING, outputEncoding.HeaderName);
            velocity.Init(props);
            //为模板变量赋值
            context = new VelocityContext();
        }

        

        /// <summary>
        /// 添加数据
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public void Put(string key, object value)
        {
            if (context == null)
                context = new VelocityContext();
            context.Put(key, value);
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public object Remove(string key)
        {
            return context.Remove(key);
        }

        /// <summary>
        /// 判断
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool ContainsKey(string key)
        {
            return context.ContainsKey(key);
        }

        /// <summary>
        /// 清空
        /// </summary>
        public void Clear()
        {
            for (int i = 0; i < context.Count; i++)
            {
                object key = context.Keys[i];
                context.Remove(key);
            }
        }

        /// <summary>
        /// 获取
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public object Get(string key)
        {
            return context.Get(key);
        }

        /// <summary>
        /// 数量
        /// </summary>
        public int Count
        {
            get
            {
                return context.Count;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public string[] Keys
        {
            get
            {
                return (string[])context.Keys;
            }
        }

        /// <summary>
        /// 渲染
        /// </summary>
        /// <param name="templateFilePath">模板文件路径(不带路径)</param>
        /// <returns></returns>
        public string Render(string templateFile)
        {
            //从文件中读取模板
            Template template = velocity.GetTemplate(templateFile);
            using (StringWriter writer = new StringWriter())
            {
                //合并模板
                template.Merge(context, writer);
                return writer.ToString();
            }
        }

        /// <summary>
        /// 输出文件
        /// </summary>
        /// <param name="templateFile">模板文件路径(不带路径)</param>
        /// <param name="saveFilePath"></param>
        /// <param name="encoding"></param>
        public void OutPut(string templateFile, string saveFilePath, Encoding encoding)
        {
            //从文件中读取模板
            Template template = velocity.GetTemplate(templateFile);
            //合并模板
            StringWriter writer = new StringWriter();
            template.Merge(context, writer);
            using (StreamWriter write2 = new StreamWriter(saveFilePath, false, encoding))
            {
                write2.Write(writer);
                write2.Flush();
                write2.Close();
            }
        }
    }
}
